use std::{
    sync::{Arc, Mutex},
    thread,
};

// Arc<Mutex<T>> 可以多线程共享且修改数据
fn arc_mutext_is_send_sync() {
    // 锁在线程中传递与移动，用Arc的结构承载
    let a: Arc<Mutex<i32>> = Arc::new(Mutex::new(1));
    let b: Arc<Mutex<i32>> = a.clone();
    let c: Arc<Mutex<i32>> = a.clone();

    /* 加锁解锁的问题
    在Rust中，当调用lock()方法获取一个Mutex的锁时，它会返回一个叫做MutexGuard的值。
    这个MutexGuard实现了Drop trait，这意味着当MutexGuard离开其作用域时，
    Rust会自动调用其drop方法。在MutexGuard的drop方法中，它会自动释放锁。
    所以不需要显式地解锁。
     */
    let handle = thread::spawn(move || {
        // 修改c的值
        let mut g = c.lock().unwrap();
        *g += 1;
    });

    {
        // 修改b的值
        let mut g = b.lock().unwrap();
        *g += 1;
    }

    handle.join().unwrap();
    // 因为a，b，c都是指向同一个对象的引用，所以a的值也被修改了。
    println!("a= {:?}", a);
}

fn main() {
    arc_mutext_is_send_sync();
}

// fn refcell_is_send() {
//     let a = RefCell::new(1);
//     thread::spawn(move || {
//         println!("a= {:?}", a);
//     });
// }

// RefCell 现在有多个 Arc 持有它，虽然 Arc 是 Send/Sync，但 RefCell 不是 Sync
// fn refcell_is_not_sync() {
//     let a = Arc::new(RefCell::new(1));
//     let b = a.clone();
//     let c = a.clone();
//     thread::spawn(move || {
//         println!("c= {:?}", c);
//     });
// }
